package vip.ola.manage.code.ctrl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import vip.ola.core.common.annotation.MethodLog;
import vip.ola.core.common.constant.RetEnum;
import vip.ola.core.common.domain.BizResponse;
import vip.ola.core.common.domain.PayPageRes;
import vip.ola.core.common.domain.PayResponse;
import vip.ola.core.common.util.MD5Util;
import vip.ola.core.common.util.MyLog;
import vip.ola.core.entity.code.CodeUser;
import vip.ola.manage.common.ctrl.BaseController;
import vip.ola.manage.common.service.RpcCommonService;
import vip.ola.manage.secruity.JwtUser;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static vip.ola.core.common.constant.CodeConstant.*;
import static vip.ola.core.common.constant.Constant.*;
import static vip.ola.core.common.constant.RetEnum.*;
import static vip.ola.core.common.constant.SysConfigConstant.TYPE_CODE;

@RestController
@RequestMapping(MGR_CONTROLLER_ROOT_PATH + "/code/user")
public class UserController extends BaseController {

    private final static MyLog _log = MyLog.getLog(UserController.class);

    @Autowired
    private RpcCommonService rpcService;

    @RequestMapping("/get")
    public ResponseEntity<?> get(long id) {
        CodeUser codeUser = rpcService.codeUserService.getById(id);
        return ResponseEntity.ok(PayResponse.buildSuccess(codeUser));
    }

    @RequestMapping("/list")
    public ResponseEntity<?> list(Long codeBusId, LocalDateTime createTimeStart, LocalDateTime createTimeEnd, String username, String realName,
                                  String mobile, Integer type, Integer status) {
        CodeUser codeUser = new CodeUser();
        codeUser.setId(codeBusId);
        codeUser.setType(type);
        codeUser.setStatus(status);
        codeUser.setUsername(username);
        codeUser.setRealName(realName);
        codeUser.setMobile(mobile);
        codeUser.setDeleted(LOGIC_NOT_DELETE);
        codeUser.setCreateTime(createTimeStart);
        codeUser.setUpdateTime(createTimeEnd);
        IPage<CodeUser> page = rpcService.codeUserService.list(getPageIndex(), getPageSize(), codeUser);
        List<JSONObject> objects = new ArrayList<>();
        for (CodeUser user : page.getRecords()) {
            JSONObject object = (JSONObject) JSON.toJSON(user);
            object.put("loginUrl", buildLoginUrl(user));
            objects.add(object);
        }
        return ResponseEntity.ok(PayPageRes.buildSuccess(objects, (int) page.getTotal()));
    }

    @RequestMapping("/count")
    public ResponseEntity<?> count(LocalDateTime createTimeStart, LocalDateTime createTimeEnd, String username, String realName,
                                   String mobile, Integer type, Integer status) {
        CodeUser codeUser = new CodeUser();
        codeUser.setType(type);
        codeUser.setStatus(status);
        codeUser.setUsername(username);
        codeUser.setRealName(realName);
        codeUser.setMobile(mobile);
        codeUser.setDeleted(LOGIC_NOT_DELETE);
        codeUser.setCreateTime(createTimeStart);
        codeUser.setUpdateTime(createTimeEnd);
        Map map = rpcService.codeUserService.count(getPageIndex(), getPageSize(), codeUser);
        return ResponseEntity.ok(PayResponse.buildSuccess(map));
    }

    private String buildLoginUrl(CodeUser codeUser) {
        // 将商户ID+商户密码+密钥 做32位MD5加密转大写,作为token传递给商户系统
        String password = codeUser.getPassword();
        String rawToken = codeUser.getId() + password + MGR_AUTH_SECRET;
        String token = MD5Util.string2MD5(rawToken).toUpperCase();
        String loginMchUrl = mainConfig.getLoginCodeUrl();
        return String.format(loginMchUrl, codeUser.getId(), token);
    }

    @RequestMapping("/add")
    @MethodLog(remark = "添加码商用户")
    public ResponseEntity<?> add(CodeUser codeUser) {
        CodeUser byName = rpcService.codeUserService.getByName(codeUser.getUsername());
        if (byName != null) {
            return ResponseEntity.ok(BizResponse.build(CODE_USERNAME_ALREADY_EXIST));
        }
        JwtUser user = getUser();
        codeUser.setRate(codeUser.getRate().divide(new BigDecimal("100")));
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        codeUser.setPassword(encoder.encode(codeUser.getPassword()));
        codeUser.setBalance(null);
        codeUser.setTotalCollNum(null);
        codeUser.setTotalCollAmount(null);
        codeUser.setTotalCollProfit(null);
        Long agentId = codeUser.getAgentId();
        if (agentId != null && !agentId.equals(0L)) {
            CodeUser agent = rpcService.codeUserService.getById(codeUser.getAgentId());
            if (agent != null) {
                codeUser.setAgentId(agent.getId());
                codeUser.setAgentRate(agent.getRate());
            }
        }
        Long codeBusId = codeUser.getCodeBusId();
        if (codeBusId != null && !codeBusId.equals(0L)) {
            CodeUser codeBus = rpcService.codeUserService.getById(codeUser.getCodeBusId());
            codeUser.setCodeBusId(codeBus.getId());
            codeUser.setCodeBusRate(codeBus.getRate());
        }
        codeUser.setRole(ROLE_CODE_NORMAL);
        codeUser.setCreateId(user.getId());
        codeUser.setCreateTime(LocalDateTime.now());
        boolean isOk = rpcService.codeUserService.add(codeUser);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    @RequestMapping("/edit")
    @MethodLog(remark = "编辑码商用户")
    public ResponseEntity<?> edit(CodeUser codeUser) {
        codeUser.setRate(codeUser.getRate().divide(new BigDecimal("100.00")));
        if (StringUtils.isNotBlank(codeUser.getPassword())) {
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            codeUser.setPassword(encoder.encode(codeUser.getPassword()));
        } else {
            codeUser.setPassword(null);
        }
        codeUser.setType(null);
        codeUser.setUsername(null);
        codeUser.setStatus(null);
        codeUser.setBalance(null);
        codeUser.setTotalCollNum(null);
        codeUser.setTotalCollAmount(null);
        codeUser.setTotalCollProfit(null);
        codeUser.setUpdateTime(LocalDateTime.now());
        boolean isOk = rpcService.codeUserService.updateById(codeUser);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    /**
     * 登录商户
     *
     * @return
     */
    @RequestMapping("/code_login")
    @MethodLog(remark = "模拟码商用户登录")
    public ResponseEntity<?> loginCode(long userId) {
        CodeUser codeUser = rpcService.codeUserService.getById(userId);
        // 将商户ID+商户密码+密钥 做32位MD5加密转大写,作为token传递给商户系统
        String password = codeUser.getPassword();
        String rawToken = userId + password + MGR_AUTH_SECRET;
        String token = MD5Util.string2MD5(rawToken).toUpperCase();
        String loginCodeUrl = mainConfig.getLoginCodeUrl();
        loginCodeUrl = String.format(loginCodeUrl, userId, token);
        JSONObject object = new JSONObject();
        object.put("userId", userId);
        object.put("token", token);
        object.put("loginCodeUrl", loginCodeUrl);
        return ResponseEntity.ok(PayResponse.buildSuccess(object));
    }

    @MethodLog(remark = "清理用户余额")
    @RequestMapping("/clean")
    public ResponseEntity<?> clean(long id) {
        CodeUser codeUser = rpcService.codeUserService.getCacheById(id);
        if (getUser().getId().equals(id)) {
            return ResponseEntity.ok(BizResponse.build(RET_COMM_RECORD_NOT_AUTH));
        }
        if (codeUser == null) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_USER_ERROR));
        }
        boolean isOk = rpcService.codeUserService.cleanAmount(id);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    @RequestMapping("/del")
    @MethodLog(remark = "删除码商用户")
    public ResponseEntity<?> del(long id) {
        CodeUser codeUser = rpcService.codeUserService.getCacheById(id);
        if (codeUser == null) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_USER_ERROR));
        }
        boolean isOk = rpcService.codeUserService.removeById(id);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    @RequestMapping("/getConfig")
    public ResponseEntity<?> getConfig() {
        JSONObject json = rpcService.rpcSysConfigService.getSysConfigObj(TYPE_CODE);
        return ResponseEntity.ok(PayResponse.buildSuccess(json));
    }

    @RequestMapping("/getUserByType")
    public ResponseEntity<?> getUserByType(int type, Long codeBusId) {
        List<Map> list = rpcService.codeUserService.getByUserType(type, codeBusId);
        return ResponseEntity.ok(PayResponse.buildSuccess(list));
    }

    @RequestMapping("/changeAmount")
    public ResponseEntity changeAmount(long id, BigDecimal amount, String bizItem, int fundDirection, String password, String orderNo, String remark) {
        // 判断输入的超级密码是否正确
        if (!MGR_SUPER_PASSWORD.equals(password)) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_MGR_SUPER_PASSWORD_NOT_MATCH));
        }
        boolean isOk = rpcService.codeUserService.updateAmountById(id, amount, bizItem, fundDirection, orderNo, remark);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }
}